package de.moc.client;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;

import org.apache.tools.ant.taskdefs.Sleep;
import org.w3c.css.sac.SimpleSelector;

import de.moc.shared.*;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SingleSelectionModel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class LectureSurveyGui implements EntryPoint {
	// List of surveys and create button
	DialogBox	dialogBox;
	CellList surveyList;
	Button buttonNew;
	Button buttonRefresh;
	
	// Results and buttons
	SurveyResultWidget surveyResultWidget;
	Button buttonEnd;
	Button buttonDelete;
	Button buttonRestart;
	
	// Start Survey Dialog
	static SurveyCreator surveyCreator;
	
	
	// Panels
	RootPanel rootPanel;
	HorizontalPanel topPanel;
	VerticalPanel overviewPanel;
	VerticalPanel resultPanel;
	HorizontalPanel buttonPanel;
	
	// utils
	static Survey		currentSurvey;
	List<Survey> 		surveys;
	Timer				refreshTimer;	
	SurveyServiceAsync surveyService = GWT.create(SurveyService.class);

	private static class SurveyCell extends AbstractCell<Survey> {
		@Override
		public void render(Context context, Survey value, SafeHtmlBuilder sb) {
			if (value == null) {
				return;
			}
			if (value == currentSurvey) {
				sb.appendHtmlConstant("<div style=\"color: #8B0000\">");
			}
			sb.append(SafeHtmlUtils.fromString("--> " + value.getName()));
			if (value == currentSurvey) {
				sb.appendHtmlConstant("</div>");
			}
	  }
	}
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		// Panels 
		rootPanel = RootPanel.get("diagramm_area");
		rootPanel.setSize("100%", "100%");		
		topPanel = new HorizontalPanel();
		overviewPanel = new VerticalPanel();
		overviewPanel.setSize("160pt", 
							  "466pt");
		resultPanel = new VerticalPanel();
		resultPanel.setSize("480pt", 
				  			"450pt");
		buttonPanel = new HorizontalPanel();
		buttonPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		buttonPanel.setSize("480pt", 
	  						"30pt");	
		
		// Results and buttons
		surveyResultWidget = new SurveyResultWidget();
		resultPanel.add(surveyResultWidget);
		
		buttonEnd = new Button("End survey");
		buttonDelete = new Button("Delete survey");
		buttonRestart = new Button("Restart survey");
		buttonEnd.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				onButtonEndClicked();
			}
		});
		buttonDelete.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				onButtonDeleteClicked();
			}
		});
		buttonRestart.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				onButtonRestartClicked();				
			}
		});		
		buttonEnd.setSize("160pt", "30pt");
		buttonDelete.setSize("160pt", "30pt");
		buttonRestart.setSize("160pt", "30pt");
		buttonPanel.add(buttonEnd);
		buttonPanel.add(buttonDelete);
		buttonPanel.add(buttonRestart);
		
		// Start Survey
		// Create a cell to render each value.
		surveyCreator = new SurveyCreator();
		surveyList = new CellList<Survey>(new SurveyCell());
		surveyList.setSelectionModel(new SingleSelectionModel<Survey>());
		surveyList.setWidth("160pt");
		surveyList.setHeight("160pt");
		buttonRefresh = new Button("Refresh");
		buttonRefresh.setSize("160pt",
				  			"30pt");
		buttonRefresh.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				onButtonShowClicked();
				surveyService.getActiveSurvey(new AsyncCallback<Survey>() {
					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}
					@Override
					public void onSuccess(Survey result) {
						for(Survey s : surveys) {
							if (s.getId().equals(result.getId())) {
								currentSurvey = s;
							}
						}
					}
				});
			}
		});	
		buttonNew = new Button("New survey");
		buttonNew.setSize("160pt",
				  			"30pt");
		buttonNew.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				dialogBox.show();
			}
		});	
		Label label = new Label("Known surveys");
		overviewPanel.add(label);
		overviewPanel.setCellHeight(label, "130pt");
		overviewPanel.setCellVerticalAlignment(label, HasVerticalAlignment.ALIGN_BOTTOM);
		
		overviewPanel.add(surveyList);
		overviewPanel.setCellHeight(surveyList, "160pt");
		overviewPanel.setCellVerticalAlignment(surveyList, HasVerticalAlignment.ALIGN_TOP);

		overviewPanel.add(buttonRefresh);
		overviewPanel.setCellHeight(buttonRefresh, "30pt");
		overviewPanel.setCellVerticalAlignment(buttonRefresh, HasVerticalAlignment.ALIGN_BOTTOM);
		
		overviewPanel.add(buttonNew);
		overviewPanel.setCellHeight(buttonNew, "30pt");
		overviewPanel.setCellVerticalAlignment(buttonNew, HasVerticalAlignment.ALIGN_BOTTOM);
		
		// Assemble the panels
		
		/*showSurveyView = new HorizontalPanel();
		showSurveyView.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		showSurveyView.setSpacing(2);
		showSurveyView.setBorderWidth(1);
		showSurveyView.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		showSurveyView.setSize("100%", "100%");
		actionPanel = new VerticalPanel();
		actionPanel.setSpacing(2);
		actionPanel.setBorderWidth(0);
		actionPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		selectionPanel = new VerticalPanel();
		startSurveyView = new VerticalPanel();
		startSurveyView.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		startSurveyView.setSpacing(2);
		startSurveyView.setBorderWidth(0);
		startSurveyView.setSize("", "");
		rootPanel.add(showSurveyView);
		showSurveyView.add(surveyResultWidget);
		surveyResultWidget.setSize("", "");
		showSurveyView.add(actionPanel);
		actionPanel.setSize("", "");
		actionPanel.add(selectionPanel);
		selectionPanel.setWidth("100%");
		actionPanel.add(buttonShow);
		buttonShow.setWidth("100%");
		actionPanel.add(buttonEnd);
		buttonEnd.setWidth("100%");
		actionPanel.add(buttonDelete);
		buttonRestart.setWidth("100%");
		actionPanel.add(buttonRestart);
		buttonDelete.setWidth("100%");
		actionPanel.add(buttonFake);
		buttonFake.setWidth("100%");
		showSurveyView.add(startSurveyView);
		startSurveyView.add(surveyCreator);
		surveyCreator.setWidth("100%");
		startSurveyView.add(buttonStart);		
		buttonStart.setWidth("100%");
		*/
		
		// initialize utilities
		//pastSurveys = new Stack<Survey>();
		///radioButtons = new Stack<RadioButton>();
		//mapping = new HashMap<RadioButton, Survey>();
		surveys = new Vector<Survey>();
		refreshTimer = new Timer() {			
			@Override
			public void run() {
				onButtonShowClicked();
				surveyService.getActiveSurvey(new AsyncCallback<Survey>() {
					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}
					@Override
					public void onSuccess(Survey result) {
						for(Survey s : surveys) {
							if (s.getId().equals(result.getId())) {
								currentSurvey = s;
							}
						}
					}
				});
			}
		};
		//refreshTimer.scheduleRepeating(1000);
		
		if (surveyService == null) {
			surveyService = GWT.create(SurveyService.class);
		}
		surveyService.getAllSurveys(new AsyncCallback<Vector<Survey>>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@SuppressWarnings("unchecked")
			@Override
			public void onSuccess(Vector<Survey> result) {
				surveys = result;
				surveyList.setRowData(result);
				surveyService.getActiveSurvey(new AsyncCallback<Survey>() {
					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}
					@Override
					public void onSuccess(Survey result) {
						for(Survey s : surveys) {
							if (s.getId().equals(result.getId())) {
								currentSurvey = s;
								surveyList.getSelectionModel().setSelected(s, true);
								onButtonShowClicked();
							}
						}
					}
				});
			}
		});

		
		// create dialogbox
		dialogBox = new DialogBox();
		VerticalPanel vPanel = new VerticalPanel();
		HorizontalPanel hPanel = new HorizontalPanel();
		Button buttonCreate = new Button("Create");
		buttonCreate.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				onButtonCreateClicked();
				dialogBox.hide();
			}
		});
		Button buttonAbort = new Button("Abort");
		buttonAbort.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});
		hPanel.add(buttonCreate);
		hPanel.add(buttonAbort);
		vPanel.add(surveyCreator);
		vPanel.add(hPanel);
		dialogBox.setWidget(vPanel);
		dialogBox.setPopupPosition(378, 250);
		
		// create structure
		resultPanel.add(buttonPanel);
		topPanel.add(overviewPanel);
		topPanel.add(resultPanel);
		rootPanel.add(topPanel);	
		
		topPanel.setWidth("100%");
		topPanel.setCellWidth(overviewPanel, "25%");
		topPanel.setCellHorizontalAlignment(overviewPanel, HasHorizontalAlignment.ALIGN_CENTER);
		topPanel.setCellWidth(resultPanel, "75%");
		topPanel.setCellHorizontalAlignment(resultPanel, HasHorizontalAlignment.ALIGN_CENTER);
		
		buttonPanel.setWidth("100%");
		buttonPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		buttonPanel.setCellHorizontalAlignment(buttonEnd,HasHorizontalAlignment.ALIGN_CENTER);
		buttonPanel.setCellHorizontalAlignment(buttonDelete,HasHorizontalAlignment.ALIGN_CENTER);
		buttonPanel.setCellHorizontalAlignment(buttonRestart,HasHorizontalAlignment.ALIGN_CENTER);
	}

	Survey getSelectedSurvey() {
		return (Survey)((SingleSelectionModel<Survey>)surveyList.getSelectionModel()).getSelectedObject();
	}
	
	void onButtonShowClicked() {
		// Initialize the service proxy.
		if (surveyService == null) {
			surveyService = GWT.create(SurveyService.class);
		}

		// Set up the callback object.
		Survey selectedSurvey = getSelectedSurvey();
		if (selectedSurvey != null) {
			String selectedId = selectedSurvey.getId();
			
			if (selectedId != null) {
				surveyService.getResult(selectedId, new AsyncCallback<Survey>() {
					public void onFailure(Throwable caught) {
						// TODO: Do something with errors.
					}
		
					@Override
					public void onSuccess(Survey result) {
						surveyResultWidget.showSurveyResults(result);
					}
				});
			}
		}
	}

	void onButtonRestartClicked() {
		// Set up the callback object.
		Survey selectedSurvey = getSelectedSurvey();
		surveys.remove(selectedSurvey);
		if (selectedSurvey != null) {
			String selectedId = selectedSurvey.getId();
			
			if (selectedId != null) {
				surveyService.resetSurvey(selectedId, new AsyncCallback<Survey>() {
					public void onFailure(Throwable caught) {
						// TODO: Do something with errors.
						surveyList.setRowData(surveys);
					}
		
					@Override
					public void onSuccess(Survey result) {
						currentSurvey = result;
						surveys.add(result);
						surveyList.setRowData(surveys);
						surveyList.getSelectionModel().setSelected(result, true);
						onButtonShowClicked();
					}
				});
			}
		}
	}
	
	void onButtonEndClicked() {
		// Initialize the service proxy.
		if (surveyService == null) {
			surveyService = GWT.create(SurveyService.class);
		}
				
		surveyService.endActiveSurvey(new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onSuccess(Boolean result) {
				// TODO Auto-generated method stub
				if (result && currentSurvey != null) {
					currentSurvey = null;
					surveyList.setRowData(surveys);
				}
			}
		});
	}
	
	void onButtonCreateClicked() {
		// Initialize the service proxy.
		if (surveyService == null) {
			surveyService = GWT.create(SurveyService.class);
		}
		
		Survey aSurvey = surveyCreator.getSurvey();
		if (aSurvey != null) { 
			final Survey tempSurvey = aSurvey;			
			surveyService.newSurvey(aSurvey, new AsyncCallback<String>() {
				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
				}
	
				@Override
				public void onSuccess(String id) {
					// TODO Auto-generated method stub
					currentSurvey = tempSurvey;
					tempSurvey.setId(id);
					surveys.add(tempSurvey);
					surveyList.setRowData(surveys);
					surveyList.getSelectionModel().setSelected(tempSurvey, true);
					onButtonShowClicked();
				}
			});
		}
	}
	
	void onButtonDeleteClicked() {
		// Initialize the service proxy.
		if (surveyService == null) {
			surveyService = GWT.create(SurveyService.class);
		}

		// Set up the callback object.
		Survey selectedSurvey = getSelectedSurvey();
		if (selectedSurvey != null) {
			String selectedId = selectedSurvey.getId();
			
			if (selectedId != null) {
				surveyService.deleteSurvey(selectedId, new AsyncCallback<Boolean>() {
					public void onFailure(Throwable caught) {
						// TODO: Do something with errors.
					}
		
					@Override
					public void onSuccess(Boolean result) {
						// dropSurveyFromList
						if (result) {						
							surveys.remove(getSelectedSurvey());
							surveyList.setRowData(surveys);
						}
					}
				});
			}
		}
	}
}
